package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.signs.AroundSign;
import com.myk.game.gobangchess.signs.LineSign;
import com.myk.game.gobangchess.signs.TitleSign;

import java.util.ArrayList;
import java.util.List;

/**
 * 遗落六子棋房间
 */
public class FSGoBangRoom extends Room {


    private int state = 0;//0为第一步子，1为提子，2为落子
    private int pushFromRow, pushFromCol, firstRow, firstCol; //推子前所在的位置

    public FSGoBangRoom(String roomName) {
        super(roomName, "\t\t鼓缶而歌提出，逆界群友辅助完善形成的新式六子棋。","遗落六子", BoardStyleData.getGoBangStyle(16,16), true,true);
    }

    @Override
    public String getRuleText() {
        return"[玩法]\n" +
                "黑方、白方轮流落1子\n" +
                "第10手棋开始落1子后，移动场上1颗己方棋子\n" +
                "[胜负]\n" +
                "获胜条件:己方棋子形成六连\n" +
                "和棋条件:无棋可走";
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (step < 9) {
            if (curGrids[row][col] == 0) { //只能落在空位置
                signList.clear();
                List<Integer> ids = new ArrayList<>();
                ids.add(getIndex(row, col));
                signList.add(new AroundSign(ids, "#00000000", "#6600FF00", 1.2f));
                curGrids[row][col] = value; //实际落子
                stepAdd();; //步数统计加增加
                WinState winState = checkWin(row, col);
                if (winState!=null) {
                    doOver(winState.winMode,winState.winMsg);
                }
                else {
                    noticeChangeMove();
                }
            }
        } else {
            if (state == 0) {//第一步
                if (curGrids[row][col] == 0) {
                    signList.clear();
                    List<Integer> ids = new ArrayList<>();
                    ids.add(getIndex(row, col));
                    signList.add(new AroundSign(ids, "#00000000", "#6600FF00", 1.2f));
                    curGrids[row][col] = value; //实际落子
                    firstRow = row;
                    firstCol = col;
                    stepAdd();; //步数统计加增加
                    WinState winState = checkWin(row, col);
                    if (winState!=null) {
                        doOver(winState.winMode,winState.winMsg);
                    }
                    else {
                        if(step == 10) {
                            signList.add(new TitleSign(0.5f, 0.45f, 0, "请移子", "#77DD7733", 4f));
                            gameTip = "现在开始落子后请移子";
                        }
                        noticeStillMove();
                    }
                }
            } else if (state == 1) {//提子
                if (curGrids[row][col] == cur && !(col == firstCol && row == firstRow)) {
                    if(step == 10){
                        int idx = signList.size() - 1;
                        signList.remove(idx);
                    }
                    List<Integer> ids = new ArrayList<>();
                    signList.add(new AroundSign(ids, "#00000000", "#6600FF00", 1.2f));
                    ids.add(getIndex(row, col));
                    curGrids[row][col] = 0; //实际落子
                    noticeStillMove();
                    pushFromRow = row;
                    pushFromCol = col;
                }
            } else {//提子后落子
                if (curGrids[row][col] == 0 && !(col == pushFromCol && row == pushFromRow)) {
                    int idx = signList.size() - 1;
                    signList.remove(idx);
                    addArrowSignal(pushFromRow, pushFromCol, row, col);
                    curGrids[row][col] = value; //实际落子
                    stepAdd();; //步数统计加增加
                    WinState winState = checkWin(row, col);
                    if (winState!=null) {
                       doOver(winState.winMode,winState.winMsg);
                    }
                    else {
                        noticeChangeMove();
                    }
                }
            }


        }
    }

    private WinState checkWin(int row, int col) {
        int winValue = 0;
        int[][] dxdy = {{1, 0}, {-1, 1}, {0, 1}, {1, 1}};
        for (int i = 0; i < dxdy.length; i++) {
            int dx = dxdy[i][0], dy = dxdy[i][1];
            int length = getJudgeLength(row, col, dx, dy) + getJudgeLength(row, col, -dx, -dy) - 1;
            if (length >= 6) {
                winValue = (curGrids[row][col] + 1) % 2 + 1;
            }
        }

        boolean gridFull = GridsUtils.getDataCount(curGrids, 0) == 0;

        if (winValue == 1) {
            return new WinState(WinMode.BLACK_WIN,player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
        } else if (winValue == 2) {
            return new WinState(WinMode.WHITE_WIN,player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
        } else if (gridFull) {
            return new WinState(WinMode.BOTH_DRAW,player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
        } else {
            return null;
        }
    }

    private int getJudgeLength(int x, int y, int dx, int dy) {
        int value = curGrids[x][y];
        int length = 0;
        while (isInGrids(x, y)) {
            if (curGrids[x][y] != value) {
                return length;
            }
            length++;
            x += dx;
            y += dy;
        }
        return length;
    }

    private boolean isInGrids(int row, int col) {
        return row >= 0 && row <= curGrids.length - 1 && col >= 0 && col <= curGrids[0].length - 1;
    }

    private void noticeChangeMove() {
        if (cur == 1) {
            noticeWhiteMove();
        } else if (cur == 2) {
            noticeBlackMove();
        }
        pushFromCol = 0;
        pushFromRow = 0;
        firstCol = 0;
        firstRow = 0;
        if (step>9){

            state++;
            if (state > 2) {
                state = 0;
            }
        }
    }

    private void noticeStillMove() {
        if (cur == 2) {
            noticeWhiteMove();
        } else if (cur == 1) {
            noticeBlackMove();
        }
        state++;
        if (state > 2){
            state = 0;
        }
    }

    public void addArrowSignal(int startRow, int startCol, int endRow, int endCol) {
        signList.add(new LineSign(getIndex(startRow, startCol), getIndex(endRow, endCol), ColorCost.MOVE_ARROW, 1));
    }

    @Override
    public void resetGrids() {
        state = 0;
        step = 0;
        gameTip = "-1";
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
    }

    public static class WinState{
        int winMode;
        String winMsg;

        public WinState(int winMode, String winMsg) {
            this.winMode = winMode;
            this.winMsg = winMsg;
        }
    }
}
